package com.xw.comm.service.impl;

import com.xw.comm.core.AnalysisObjectResult;
import com.xw.comm.core.WorkTarget;
import com.xw.comm.entity.Common;
import com.xw.comm.entity.IdentifyObject;
import com.xw.comm.entity.map.BaseMapObject;
import com.xw.comm.entity.run.BaseStateEnum;
import com.xw.comm.entity.run.DoorObject;
import com.xw.comm.entity.run.MainObject;
import com.xw.comm.entity.task.CreateTarget;
import com.xw.comm.entity.task.TaskTarget;
import com.xw.comm.service.RunService;
import com.xw.comm.service.SerialService;
import com.xw.comm.service.map.BackgroundMapService;
import com.xw.comm.utils.ObjectQueueUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author xiongwei_vendor
 * @date 2021/9/24 14:26
 */
@Slf4j
@Service
public class RunServiceImpl implements RunService {

    /**
     * 是否运行，还是终止
     */
    boolean isRun = true;

    /**
     * 任务线程
     */
    @Autowired
    private TaskExecutor produceTaskExecutor;

    @Autowired
    private BackgroundMapService mapService;

    @Autowired
    private SerialService serialService;

    /**
     * 识别后，分析的结果
     */
    private AnalysisObjectResult analysisObjectResult;

    /**
     * 工作目标
     */
    private WorkTarget workTarget;

    private Thread commonThread;

    private void init() {

        analysisObjectResult = new AnalysisObjectResult();

        produceTaskExecutor.execute(this);

        commonThread = new Thread(runnable);
        commonThread.start();
    }

    @Override
    public void run() {

        while (isRun) {
            try {
                IdentifyObject object = ObjectQueueUtil.identifyQueue.take();

                analysisObjectResult.dataDistribution(object);
                analysisObjectResult.calculation();

                TaskTarget taskTarget = workTarget.getTaskTarget();

                if (taskTarget != null) {
                    // 希望可以得出一个小目标
                    workTarget.createTargetByMainInfo(analysisObjectResult.getMainObject());
                }
                if (null == workTarget.getCreateTarget()) {
                    return;
                }

                CreateTarget createTarget = workTarget.getCreateTarget();
                MainObject mainObject = analysisObjectResult.getMainObject();
                List<DoorObject> doorObjectList = mainObject.getBaseMapObject().getDoorObjectList();
                DoorObject targetDoorObject = null;
                for (DoorObject doorObject : doorObjectList) {
                    String doorMapId = doorObject.getDoorMapObject().getObjectId();
                    String createTargetMapId = createTarget.getBaseMapObject().getObjectId();
                    if (doorMapId.equals(createTargetMapId)) {
                        targetDoorObject = doorObject;
                        break;
                    }
                }

                if (targetDoorObject == null) {
                    // 没有发现过图的地方
                    return;
                }

                mainObject.addDoorObject(targetDoorObject);

                synchronized (commonThread) {
                    commonThread.notify();
                }

            } catch (InterruptedException e) {
                log.error("运行失败！！！", e);
            }
        }
        log.info("停下活动...");
    }


    /**
     * 开始
     */
    @Override
    public void start() {
        if (isRun) {
            return;
        }
        isRun = true;
        produceTaskExecutor.execute(this);
    }

    /**
     * 结束
     */
    @Override
    public void stop() {
        if (isRun) {
            isRun = false;
        }
    }

    /**
     * 设置任务了
     *
     * @param mapId 地图id
     * @return 是否设置成功
     */
    @Override
    public boolean setTask(String mapId) {
        BaseMapObject baseMapObject = findObjectInfo(mapId);
        TaskTarget taskTarget = new TaskTarget();
        taskTarget.setBaseMapObject(baseMapObject);
        taskTarget.setBaseStateEnum(BaseStateEnum.NON_COMBAT);

        if (null == workTarget) {
            workTarget = new WorkTarget();
            workTarget.setTaskTarget(taskTarget);
        } else {
            workTarget.setTaskTarget(taskTarget);
        }

        return true;
    }

    /**
     * 查找对象的信息
     *
     * @param id 对应id
     * @return 地图对象
     */
    private BaseMapObject findObjectInfo(String id) {
        // TODO 还没有实现逻辑，后续赶紧实现了

        return new BaseMapObject();
    }


    /**
     * 移动命令
     */
    private void moveCommon() throws InterruptedException {

        synchronized (commonThread) {
            MainObject mainObject = analysisObjectResult.getMainObject();
            if (mainObject == null) {
                return;
            }
            if (mainObject.getBaseStateEnum() == BaseStateEnum.NON_COMBAT) {
                // 非战斗命令
                nonCombatCommon(mainObject);
            } else {
                fightCommon();
            }
            BaseMapObject mainBackgroundMap = mainObject.getBaseMapObject();

        }
    }


    private void fightCommon() {

    }

    /**
     * 非战斗
     */
    private void nonCombatCommon(MainObject mainObject) throws InterruptedException {
        DoorObject currentDoorObject = mainObject.getCurrentDoorObject();
        if (null == currentDoorObject || currentDoorObject.getRelationshipEnum() == null) {
            commonThread.wait();
        } else {
            switch (currentDoorObject.getRelationshipEnum()) {
                case UP:
                    serialService.sendMessage(Common.UP);
                    break;
                case DOWN:
                    serialService.sendMessage(Common.DOWN);
                    break;
                case LEFT:
                    serialService.sendMessage(Common.LEFT);
                    break;
                case RIGHT:
                    serialService.sendMessage(Common.RIGHT);
                    break;
                default:
                    break;
            }
            Thread.sleep(1000);

            // 数据使用完，就清零吧
            currentDoorObject.setRelationshipEnum(null);
        }
    }

    /**
     * 命令循环运行线程
     */
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            while (true) {
                try {
                    log.info("循环了一次");
                    moveCommon();
                } catch (InterruptedException e) {
                    log.error("中断出现问题 = {}", e.getMessage(), e);
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException interruptedException) {
                        log.error("睡眠出现问题 = {}", e.getMessage(), e);
                        break;
                    }
                }
            }
        }
    };


    public static void main(String[] arg0) {
        RunServiceImpl impl = new RunServiceImpl();
        impl.init();
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (impl.commonThread) {
                impl.commonThread.notify();
            }
        }

    }


}
